import { gg } from "./Game";
import { LocalStorageManager } from "./manger/LocalStorageManager";
import { LoggerManager } from "./manger/LoggerManager";
/**
 * 游戏数据类，可存储到localStorage中，泛型T为要存储的数据结构
 */
export abstract class GameStorage<T = any> {
    /**游戏存储key前缀 */
    public static keyPrefix = "game_snake"
    protected readonly key: string = "";
    protected _data: {};

    /**存储的数据 */
    public get data(): T {
        return this._data as T
    }
    constructor(key?: string) {
        const cst: any = this.constructor
        const dataType = cst.typeClz
        if (!dataType) {
            return
        }
        if (!key && cst.key) {
            key = GameStorage.keyPrefix + "_" + cst.key
        }
        if (!key) {
            key = GameStorage.keyPrefix + "_" + dataType.name
        }
        this.key = key;


        if (!this.load() && dataType) {
            this._data = new dataType()
            // this.initFromConfig()
            this.save();
        }
        else {
            let newData = new dataType();
            let prePropNames = Object.getOwnPropertyNames(this._data);
            let newPropNames = Object.getOwnPropertyNames(newData);
            if (prePropNames.length != newPropNames.length) {
                for (let i = 0; i < newPropNames.length; i++) {
                    let propName = newPropNames[i];
                    if (this._data[propName] == undefined) {
                        this.data[propName] = newData[propName];
                    }
                }
                this.save();
            }
        }
    }

    /**
     *初始化数据,由管理器统一调用，一般是从远程获取数据     
     */
    initialize(): Promise<void> { return null }

    /**当跨天 */
    onCrossDay() { }
    /**
     * 从配置文件初始化数据
     */
    // abstract initFromConfig(): void

    public save() {
        GameStorage.setItem(this.key, JSON.stringify(this._data))
    }

    public load(): boolean {
        let d = GameStorage.getItem(this.key)
        if (!d || d.length == 0) {
            return false;
        }
        LoggerManager.instance().log("load data:", d);
        this._data = JSON.parse(d);
        return true;
    }

    public remove() {
        LoggerManager.instance().log("remove data:");
        cc.sys.localStorage.removeItem(this.key);
    }

    public static setItem(key: string, data: string) {
        cc.sys.localStorage.setItem(key, data);
    }

    public static getItem(key: string): string {
        let d = cc.sys.localStorage.getItem(key);
        d = cc.sys.localStorage.getItem(key);
        if (d == undefined || d == '') d = null;
        return d
    }
}


/**
 * 注册到LocalStorageManager中，由LocalStorageManager统一管理
 * @param typeClz 存储类型对象的Class
 * @param key 存储类型对象的key，传了typeClz才需要
 * @returns 
 */
export function regStorage<T extends {}>(typeClz?: new () => T, key: string = ''): ClassDecorator {
    //@ts-ignore
    if (!regStorage.clzArr) {
        //@ts-ignore
        regStorage.clzArr = []
    }
    return function (target) {
        if (typeClz) {
            Object.defineProperty(
                target,
                'typeClz',
                {
                    value: typeClz,
                    writable: false,
                    enumerable: false
                }
            )
            Object.defineProperty(
                target,
                'key',
                {
                    value: key,
                    writable: false,
                    enumerable: false
                }
            )
        }
        if (gg.isInitComplete()) {
            const storage = LocalStorageManager.instance().regStorage(target)
            storage.initialize && storage.initialize()
        } else {
            //@ts-ignore
            regStorage.clzArr.push(target)
        }


    }
}
